﻿using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.Win32;
using System.Diagnostics;
using System.Configuration.Install;
using System.Collections.Specialized;
using System.ServiceProcess;
using System.IO;
using System.Reflection;

namespace Common.Com
{
    public class ServiceHelper
    {
        /// <summary>
        /// 安装服务
        /// </summary>
        /// <param name="stateSaver"></param>
        /// <param name="filepath"></param>
        /// <param name="serviceName"></param>
        public static void InstallService(string filepath, string serviceName)
        {
            System.ServiceProcess.ServiceController service = new System.ServiceProcess.ServiceController(serviceName);
            if (!ServiceExist(serviceName))
            {

                //Install Service   

                AssemblyInstaller myAssemblyInstaller = new AssemblyInstaller();

                myAssemblyInstaller.UseNewContext = true;

                myAssemblyInstaller.Path = filepath;
                IDictionary stateSaver = new Hashtable();
                stateSaver.Clear();
                myAssemblyInstaller.Install(stateSaver);

                myAssemblyInstaller.Commit(stateSaver);

                myAssemblyInstaller.Dispose();

                //--Start Service   

                service.Start();

            }

            else
            {

                if (service.Status != System.ServiceProcess.ServiceControllerStatus.Running && service.Status != System.ServiceProcess.ServiceControllerStatus.StartPending)
                {

                    service.Start();

                }

            }

        }

        /// <summary>
        /// 卸载服务
        /// </summary>
        /// <param name="filepath"></param>
        /// <param name="serviceName"></param>
        public static void UnInstallService(string filepath, string serviceName)
        {

            try
            {

                if (ServiceExist(serviceName))
                {

                    //UnInstall Service   

                    AssemblyInstaller myAssemblyInstaller = new AssemblyInstaller();

                    myAssemblyInstaller.UseNewContext = true;

                    myAssemblyInstaller.Path = filepath;

                    myAssemblyInstaller.Uninstall(null);

                    myAssemblyInstaller.Dispose();

                }

            }

            catch (Exception ex)
            {

                throw new Exception("unInstallServiceError/n" + ex.Message);

            }

        }


        /// <summary>
        /// 启动服务(OK)
        /// </summary>
        /// <param name="serviceName"></param>
        public static void StartService(string serviceName)
        {

            if (ServiceExist(serviceName))
            {

                System.ServiceProcess.ServiceController service = new System.ServiceProcess.ServiceController(serviceName);

                if (service.Status != System.ServiceProcess.ServiceControllerStatus.Running && service.Status != System.ServiceProcess.ServiceControllerStatus.StartPending)
                {

                    service.Start();

                    for (int i = 0; i < 60; i++)
                    {

                        service.Refresh();

                        System.Threading.Thread.Sleep(1000);

                        if (service.Status == System.ServiceProcess.ServiceControllerStatus.Running)
                        {

                            break;

                        }

                        if (i == 59)
                        {

                            throw new Exception(serviceName + "====>：启动失败");

                        }

                    }

                }

            }

        }

        /// <summary>
        /// 停止服务(OK)
        /// </summary>
        /// <param name="serviceName"></param>
        public static void StopService(string serviceName)
        {

            if (ServiceExist(serviceName))
            {

                System.ServiceProcess.ServiceController service = new System.ServiceProcess.ServiceController(serviceName);

                if (service.Status == System.ServiceProcess.ServiceControllerStatus.Running)
                {

                    service.Stop();

                    for (int i = 0; i < 60; i++)
                    {

                        service.Refresh();

                        System.Threading.Thread.Sleep(1000);

                        if (service.Status == System.ServiceProcess.ServiceControllerStatus.Stopped)
                        {

                            break;

                        }

                        if (i == 59)
                        {

                            throw new Exception(serviceName + "====>：启动失败");

                        }

                    }

                }

            }

        }


        /// <summary>   
        /// 修改服务的启动项 2为自动,3为手动 4 为禁用  (OK)
        /// </summary>   
        /// <param name="startType"></param>   
        /// <param name="serviceName"></param>   
        /// <returns></returns>   
        public static bool ChangeServiceStartType(int startType, string serviceName)
        {
            try
            {
                RegistryKey regist = Registry.LocalMachine;
                RegistryKey sysReg = regist.OpenSubKey("SYSTEM");
                RegistryKey currentControlSet = sysReg.OpenSubKey("CurrentControlSet");
                RegistryKey services = currentControlSet.OpenSubKey("Services");
                RegistryKey servicesName = services.OpenSubKey(serviceName, true);
                servicesName.SetValue("Start", startType);
            }
            catch (Exception ex)
            {

                return false;
            }
            return true;


        }


        /// <summary>   
        /// 获取服务启动类型 2为自动 3为手动 4 为禁用  (OK) 
        /// </summary>   
        /// <param name="serviceName"></param>   
        /// <returns></returns>   
        public static string GetServiceStartType(string serviceName)
        {
            try
            {
                RegistryKey regist = Registry.LocalMachine;
                RegistryKey sysReg = regist.OpenSubKey("SYSTEM");
                RegistryKey currentControlSet = sysReg.OpenSubKey("CurrentControlSet");
                RegistryKey services = currentControlSet.OpenSubKey("Services");
                RegistryKey servicesName = services.OpenSubKey(serviceName, true);
                return servicesName.GetValue("Start").ToString();
            }
            catch (Exception ex)
            {

                return string.Empty;
            }

        }

        /// <summary>   
        /// 验证服务是否启动(OK)
        /// </summary>   
        /// <returns></returns>   
        public static bool ServiceIsRunning(string serviceName)
        {
            ServiceController service = new ServiceController(serviceName);
            if (service.Status == ServiceControllerStatus.Running)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>   
        /// 服务是否存在(OK)
        /// </summary>   
        /// <param name="serviceName"></param>   
        /// <returns></returns>   
        public static bool ServiceExist(string serviceName)
        {
            try
            {
                string m_ServiceName = serviceName;
                ServiceController[] services = ServiceController.GetServices();
                foreach (ServiceController s in services)
                {
                    if (s.ServiceName.ToLower() == m_ServiceName.ToLower())
                    {
                        return true;
                    }
                }
                return false;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    }
}
